package com.cityp.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cityp.bean.AllUser;
import com.cityp.bean.ResultBean;
import com.cityp.bean.UserLoginParam;
import com.cityp.mapper.UserListMapper;
import com.cityp.mapper.UserMapper;
import com.cityp.service.IUserService;
import com.cityp.utils.JwtToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;

/**
 * @ClassName: UserServiceImpl
 * @Description:
 * @author: Kowk
 * @since:1.0.0
 */
@Service
public class UserServiceImpl implements IUserService {
    /**
     * @Description: 登陆之后返回token
     * @Param: [name, password, request]
     * @return: com.cityp.bean.ResultBean
     */
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserListMapper userListMapper;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtToken jwtToken;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public ResultBean login(String name, String password, HttpServletRequest request) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(name);
        if(userDetails==null|| !passwordEncoder.matches(password,userDetails.getPassword())){
            return ResultBean.err("用户名或密码错误");
        }
        if(!userDetails.isEnabled()){
            return ResultBean.err("账号被禁用，请联系管理人员");
        }
        //更新登陆用户对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                userDetails,null,userDetails.getAuthorities()
        );
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);


        String token = jwtToken.generateToken(userDetails);
        Map<String,String> tokenMap = new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);

        //将用户IP和登陆时间存入数据库
        //String ip = request.getRemoteAddr();
        String ip = getIpAddr(request);
        System.out.println(ip);
        Timestamp time = getTimeNow();
        //System.out.println(time);
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AllUser user = (AllUser) principal;
        //System.out.println(user.getUserId());
        userListMapper.updateUserLoginLog(user.getUserId(),user.getUsername(),ip,time);
        return ResultBean.success("登陆成功",tokenMap);
    }

    public static String getIpAddr(HttpServletRequest request) {
        /** 
        * @Description: 获取当前用户ip地址 
        * @Param: [request] 
        * @return: java.lang.String 
        */ 
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    try {
                        ipAddress = InetAddress.getLocalHost().getHostAddress();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null) {
                if (ipAddress.contains(",")) {
                    return ipAddress.split(",")[0];
                } else {
                    return ipAddress;
                }
            } else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    /**
     * @Description: 根据用户名获取用户
     * @Param: [username]
     * @return: com.cityp.bean.AllUser
     */
    @Override
    public AllUser getAdminByUserName(String username){

        return userMapper.selectOne(new QueryWrapper<AllUser>().eq("user_name",username).eq("enabled",1));
    }

    @Override
    public ResultBean register(UserLoginParam user) {
        /**
        * @Description: 用户注册接口
        * @Param: [user]
        * @return: com.cityp.bean.ResultBean
        */
        AllUser allUser = new AllUser();
        if(user.getUserName()!=null&&user.getUserPassword()!=null){
            if(userMapper.selectOne(new QueryWrapper<AllUser>().eq("user_name",user.getUserName()))!=null){
                return ResultBean.err("用户名已经存在");
            }
            allUser.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
            allUser.setUserName(user.getUserName());
            allUser.setUserState(1);
            String uuid = UUID.randomUUID().toString().replace("-","");
            allUser.setUserId(uuid);
            Timestamp time = getTimeNow();
            allUser.setUserCreatTime(time);
            userMapper.insert(allUser);
            return ResultBean.success("注册成功");
        }
        return  ResultBean.err("注册失败，账号或密码输入有误");
    }

    public Timestamp getTimeNow(){
        Date d = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateNow = simpleDateFormat.format(d);
        return Timestamp.valueOf(dateNow);
    }

    @Override
    public boolean saveBatch(Collection<AllUser> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<AllUser> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean updateBatchById(Collection<AllUser> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(AllUser entity) {
        return false;
    }

    @Override
    public AllUser getOne(Wrapper<AllUser> queryWrapper, boolean throwEx) {
        return null;
    }

    @Override
    public Map<String, Object> getMap(Wrapper<AllUser> queryWrapper) {
        return null;
    }

    @Override
    public <V> V getObj(Wrapper<AllUser> queryWrapper, Function<? super Object, V> mapper) {
        return null;
    }

    @Override
    public BaseMapper<AllUser> getBaseMapper() {
        return null;
    }
}
